<template>
  <div class="page-container">
    <div class="page-header">
      <h1>스테이킹 본금 관리</h1>
      <p>스테이킹 관리 / 본금 관리</p>
    </div>

    <div class="page-content">
      <!-- 검색 영역 -->
      <el-card class="search-card">
        <div class="search-container">
          <div class="search-left">
            <span class="search-label">전체 스테이킹 사용자</span>
          </div>
          <div class="search-right">
            <el-input
              v-model="searchForm.search"
              placeholder="이름, 신분증, 휴대전화로 검색"
              class="search-input"
              clearable
              @keyup.enter="fetchStakingList"
            >
              <template #append>
                <el-button type="primary" @click="fetchStakingList">검색</el-button>
              </template>
            </el-input>
          </div>
        </div>
      </el-card>

      <!-- 스테이킹 목록 -->
      <el-card class="table-card">
        <template #header>
          <div class="table-header">
            <span>스테이킹 목록</span>
            <el-button
              type="primary"
              size="small"
              :loading="isExporting"
              @click="handleExportExcel"
            >
              Excel 내보내기
            </el-button>
          </div>
        </template>
        <el-table
          v-loading="loading"
          :data="stakingList"
          stripe
          style="width: 100%"
        >
          <el-table-column prop="user.name" label="이름" width="120" />
          <el-table-column prop="user.idNumber" label="신분증" width="180" />
          <el-table-column prop="user.mobileNumber" label="휴대전화" width="130" />
          <el-table-column label="스테이킹 본금 (NEAR)" width="180" align="right">
            <template #default="{ row }">
              <span class="amount">{{ formatNearAmount(row.stakedAmount) }}</span>
            </template>
          </el-table-column>
          <el-table-column label="누적 수익 (NEAR)" width="220" align="right">
            <template #default="{ row }">
              <div class="amount reward">
                <el-tag size="small" effect="plain" type="info" class="label-chip">장부 기준</el-tag>
                <span class="amount-value">{{ formatNearAmount(row.ledgerTotalRewardsNear ?? row.totalRewardsNear) }} NEAR</span>
              </div>
              <div v-if="hasStoredRewardDiff(row)" class="sub-hint">
                저장된 기록: {{ formatNearAmount(row.storedTotalRewardsNear) }} NEAR
              </div>
            </template>
          </el-table-column>
          <el-table-column label="일일 수익률" width="100" align="center">
            <template #default="{ row }">
              <el-tag type="success">{{ formatPercentage(row.dailyRewardRate) }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="예상 일일 수익 (NEAR)" width="180" align="right">
            <template #default="{ row }">
              <span class="amount expected">{{ formatNearAmount(row.expectedDailyReward) }}</span>
            </template>
          </el-table-column>
          <el-table-column label="마지막 정산일" width="180">
            <template #default="{ row }">
              {{ row.lastSettlementDate ? formatDate(row.lastSettlementDate) : '미정산' }}
            </template>
          </el-table-column>
          <el-table-column label="상태" width="100" align="center">
            <template #default="{ row }">
              <el-tag :type="getStatusTagType(row.status)" size="small">
                {{ getStatusText(row.status) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="작업" width="420" fixed="right">
            <template #default="{ row }">
              <el-button type="primary" size="small" @click="handleAdjustAssets(row)">
                본금 조정
              </el-button>
              <el-button type="success" size="small" @click="handleAdjustRate(row)">
                수익률 조정
              </el-button>
              <el-button type="warning" size="small" @click="handleSettleAll(row)">
                제전 결산
              </el-button>
            </template>
          </el-table-column>
        </el-table>

        <!-- 페이지네이션 -->
        <div class="pagination-container">
          <el-pagination
            v-model:current-page="pagination.page"
            v-model:page-size="pagination.limit"
            :total="pagination.total"
            :page-sizes="[10, 20, 50, 100]"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="handleSizeChange"
            @current-change="handlePageChange"
          />
        </div>
      </el-card>
    </div>

    <!-- 수익률 조정 대화상자 -->
    <el-dialog
      v-model="adjustRateDialogVisible"
      title="일일 수익률 조정"
      width="500px"
    >
      <el-form v-if="selectedStaking" :model="adjustRateForm" label-width="120px">
        <el-form-item label="사용자">
          <span>{{ selectedStaking.user.name }} ({{ selectedStaking.user.idNumber }})</span>
        </el-form-item>
        <el-form-item label="현재 수익률">
          <span>{{ formatPercentage(selectedStaking.dailyRewardRate) }}</span>
        </el-form-item>
        <el-form-item label="새로운 수익률" required>
          <el-input-number
            v-model="adjustRateForm.dailyRewardRate"
            :min="0"
            :max="1"
            :precision="6"
            :step="0.0001"
            style="width: 100%"
          />
          <span style="margin-left: 8px; color: #909399;">
            (예: 0.02 = 2%)
          </span>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="adjustRateDialogVisible = false">취소</el-button>
        <el-button type="primary" :loading="submitting" @click="confirmAdjustRate">
          확인
        </el-button>
      </template>
    </el-dialog>

    <!-- 자산 조정 대화상자 -->
    <el-dialog
      v-model="adjustAssetsDialogVisible"
      title="자산 항목 조정"
      width="520px"
    >
      <el-alert
        type="warning"
        :closable="false"
        class="dialog-tip"
        description="자유 보유, 스테이킹 잠금, 보상 금액을 직접 조정합니다. 입력한 NEAR 값을 기준으로 장부가 재계산되며, 이후 수익 분배는 새 수치에 따라 진행됩니다."
      />
      <el-form v-if="selectedStaking" :model="adjustAssetsForm" label-width="170px">
        <el-form-item label="사용자">
          <span>{{ selectedStaking.user.name }} ({{ selectedStaking.user.idNumber }})</span>
        </el-form-item>
        <el-form-item label="스테이킹 본금 (NEAR)">
          <div class="form-row">
            <el-input-number
              v-model="adjustAssetsForm.stakedAmountNear"
              :min="0"
              :precision="4"
              :step="1"
              style="width: 100%"
            />
            <div class="field-hint">
              일일 수익은 이 본금을 기준으로 계산됩니다.
            </div>
          </div>
        </el-form-item>
        <el-form-item label="스테이킹 잠금 (NEAR)">
          <div class="form-row">
            <el-input-number
              v-model="adjustAssetsForm.lockedAmountNear"
              :min="0"
              :precision="4"
              :step="1"
              style="width: 100%"
            />
            <div class="field-hint">
              추천 보상 등 잠금 금액이며, 현재 수익 계산에는 포함되지 않습니다.
            </div>
          </div>
        </el-form-item>
        <el-form-item label="누적 스테이킹 보상 (KRW)">
          <div class="form-row">
            <el-input-number
              v-model="adjustAssetsForm.totalRewardsKrw"
              :min="0"
              :step="1000"
              style="width: 100%"
            />
            <div class="field-hint">
              장부 기준(표시 값): ₩{{ formatKrwAmount(adjustAssetsForm.totalRewardsKrw) }}
            </div>
            <div class="field-hint">
              스테이킹 기록 저장 값: {{ formatNearAmount(storedTotalRewardsNear) }} NEAR
            </div>
          </div>
        </el-form-item>
        <el-form-item label="출금 가능한 스테이킹 보상 (KRW)">
          <div class="form-row">
            <el-input-number
              v-model="adjustAssetsForm.availableRewardsKrw"
              :min="0"
              :step="1000"
              style="width: 100%"
            />
            <div class="field-hint">
              장부 기준(표시 값): ₩{{ formatKrwAmount(adjustAssetsForm.availableRewardsKrw) }}
            </div>
            <div class="field-hint">
              저장된 값: {{ formatNearAmount(storedAvailableRewardsNear) }} NEAR
            </div>
            <div class="field-hint">
              실제 출금 가능한 보상(NEAR) 값입니다. 필요 시 장부 수치와 일치하도록 조정하세요.
            </div>
            <div class="field-hint">
              자유 보유 잔액도 동일한 NEAR 값으로 동기화됩니다. 현재 조회 기준 ₩{{ formatKrwAmount(selectedStaking ? selectedStaking.freeHoldingKrw : 0) }}
            </div>
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="adjustAssetsDialogVisible = false">취소</el-button>
        <el-button type="primary" :loading="assetsSubmitting" @click="confirmAdjustAssets">
          확인
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { api } from '@/utils/request'
import { exportToExcel, formatNearAmount as formatNearForExcel, formatDateTimeString, formatPercentage as formatPercentageForExcel } from '@/utils/exportExcel'
import type { ExportHeader } from '@/utils/exportExcel'

interface UserStaking {
  id: number
  userId: number
  stakedAmount: number
  lockedAmount: number
  availableRewardsNear: number
  storedAvailableRewardsNear: number
  ledgerAvailableRewardsNear: number
  ledgerAvailableRewardsKrw: number
  totalRewardsNear: number
  storedTotalRewardsNear: number
  ledgerTotalRewardsNear: number
  ledgerTotalRewardsKrw: number
  freeHoldingNear: number
  freeHoldingKrw: number
  dailyRewardRate: number
  expectedDailyReward: number
  lastSettlementDate: string | null
  status: string
  startDate: string | null
  user: {
    id: number
    name: string
    idNumber: string
    mobileNumber: string
  }
}

const loading = ref(false)
const isExporting = ref(false)
const submitting = ref(false)
const stakingList = ref<UserStaking[]>([])

const searchForm = reactive({
  search: ''
})

const pagination = reactive({
  page: 1,
  limit: 20,
  total: 0,
  totalPages: 0
})

const adjustRateDialogVisible = ref(false)
const selectedStaking = ref<UserStaking | null>(null)

const adjustRateForm = reactive({
  dailyRewardRate: 0
})

const adjustAssetsDialogVisible = ref(false)
const assetsSubmitting = ref(false)
const adjustAssetsForm = reactive({
  stakedAmountNear: 0,
  lockedAmountNear: 0,
  totalRewardsKrw: 0,
  availableRewardsKrw: 0
})
const storedAvailableRewardsNear = ref(0)
const storedTotalRewardsNear = ref(0)
const ledgerTotalRewardsKrw = ref(0)
const ledgerAvailableRewardsKrw = ref(0)

// 格式化NEAR数量
const formatNearAmount = (amount: number): string => {
  return amount.toFixed(4)
}

const formatKrwAmount = (amount: number): string => {
  return amount.toLocaleString('ko-KR', {
    minimumFractionDigits: 0,
    maximumFractionDigits: 0
  })
}

// 格式化百分比
const formatPercentage = (rate: number): string => {
  return `${(rate * 100).toFixed(2)}%`
}

const hasStoredRewardDiff = (row: UserStaking): boolean => {
  const ledgerValue = row.ledgerTotalRewardsNear ?? row.totalRewardsNear
  return Math.abs(ledgerValue - row.storedTotalRewardsNear) > 0.0001
}

// 格式化日期
const formatDate = (dateStr: string): string => {
  if (!dateStr) return '-'
  const date = new Date(dateStr)
  return date.toLocaleString('ko-KR', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  })
}

// 获取质押列表
const fetchStakingList = async () => {
  loading.value = true
  try {
    const response: any = await api.get('/api/admin/staking/staking-list', {
      params: {
        page: pagination.page,
        limit: pagination.limit,
        search: searchForm.search
      }
    })

    // admin의 request 인터셉터가 이미 data 객체를 반환하므로 response.data에 직접 접근
    if (response.data) {
      stakingList.value = response.data.list
      pagination.total = response.data.total
      pagination.totalPages = response.data.totalPages
    }
  } catch (error: any) {
    console.error('스테이킹 목록 조회 실패:', error)
    ElMessage.error(error.message || '스테이킹 목록을 불러오지 못했습니다')
  } finally {
    loading.value = false
  }
}

// Excel 내보내기
const handleExportExcel = async () => {
  try {
    isExporting.value = true

    // 构建导出参数（与当前筛选条件一致）
    const params: any = {
      exportAll: 'true', // 导出全部数据
      search: searchForm.search
    }

    // 调用API获取全部数据
    const response: any = await api.get('/api/admin/staking/staking-list', { params })

    if (!response.data || !response.data.list || response.data.list.length === 0) {
      ElMessage.warning('내보낼 데이터가 없습니다')
      return
    }

    const list = response.data.list

    // 定义导出的列
    const headers: ExportHeader[] = [
      { label: '이름', prop: 'user.name' },
      { label: '신분증', prop: 'user.idNumber' },
      { label: '휴대전화', prop: 'user.mobileNumber' },
      {
        label: '스테이킹 본금 (NEAR)',
        prop: 'stakedAmount',
        formatter: (val) => formatNearForExcel(val)
      },
      {
        label: '누적 수익 (NEAR)',
        prop: 'totalRewardsNear',
        formatter: (val) => formatNearForExcel(val)
      },
      {
        label: '일일 수익률',
        prop: 'dailyRewardRate',
        formatter: (val) => formatPercentageForExcel(val)
      },
      {
        label: '예상 일일 수익 (NEAR)',
        prop: 'expectedDailyReward',
        formatter: (val) => formatNearForExcel(val)
      },
      {
        label: '마지막 정산일',
        prop: 'lastSettlementDate',
        formatter: (val) => val ? formatDateTimeString(val) : '미정산'
      }
    ]

    // 导出Excel
    exportToExcel({
      fileName: '스테이킹본금관리',
      headers,
      data: list,
      sheetName: '스테이킹 목록'
    })

    ElMessage.success(`${list.length}건의 데이터를 성공적으로 내보냈습니다`)
  } catch (error: any) {
    console.error('Excel 내보내기 실패:', error)
    ElMessage.error(error.message || 'Excel 내보내기에 실패했습니다')
  } finally {
    isExporting.value = false
  }
}

// 打开调整费率对话框
const handleAdjustRate = (row: UserStaking) => {
  selectedStaking.value = row
  adjustRateForm.dailyRewardRate = row.dailyRewardRate
  adjustRateDialogVisible.value = true
}

// 수익률 조정 확인
const confirmAdjustRate = async () => {
  if (!selectedStaking.value) return

  submitting.value = true
  try {
    await api.post('/api/admin/staking/adjust-daily-rate', {
      userId: selectedStaking.value.userId,  // 使用userId而不是applicationId
      dailyRewardRate: adjustRateForm.dailyRewardRate
    })

    ElMessage.success('일일 수익률이 성공적으로 조정되었습니다')
    adjustRateDialogVisible.value = false
    await fetchStakingList()
  } catch (error: any) {
    console.error('수익률 조정 실패:', error)
    ElMessage.error(error.message || '수익률 조정에 실패했습니다')
  } finally {
    submitting.value = false
  }
}

// 자산 항목 조정 다이얼로그 열기
const handleAdjustAssets = (row: UserStaking) => {
  selectedStaking.value = row
  adjustAssetsForm.stakedAmountNear = row.stakedAmount
  adjustAssetsForm.lockedAmountNear = row.lockedAmount
  adjustAssetsForm.totalRewardsKrw = row.ledgerTotalRewardsKrw ?? row.freeHoldingKrw
  adjustAssetsForm.availableRewardsKrw = row.ledgerAvailableRewardsKrw ?? row.freeHoldingKrw
  storedAvailableRewardsNear.value = row.storedAvailableRewardsNear
  storedTotalRewardsNear.value = row.storedTotalRewardsNear
  ledgerTotalRewardsKrw.value = row.ledgerTotalRewardsKrw ?? row.freeHoldingKrw
  ledgerAvailableRewardsKrw.value = row.ledgerAvailableRewardsKrw ?? row.freeHoldingKrw
  adjustAssetsDialogVisible.value = true
}

// 자산 항목 조정 확인
const confirmAdjustAssets = async () => {
  if (!selectedStaking.value) return

  assetsSubmitting.value = true
  try {
    await api.post('/api/admin/staking/adjust-assets', {
      userId: selectedStaking.value.userId,
      stakedAmountNear: adjustAssetsForm.stakedAmountNear,
      lockedAmountNear: adjustAssetsForm.lockedAmountNear,
      totalRewardsKrw: adjustAssetsForm.totalRewardsKrw,
      availableRewardsKrw: adjustAssetsForm.availableRewardsKrw
    })

    ElMessage.success('자산 항목이 성공적으로 조정되었습니다')
    adjustAssetsDialogVisible.value = false
    await fetchStakingList()
  } catch (error: any) {
    console.error('자산 조정 실패:', error)
    ElMessage.error(error.message || '자산 조정에 실패했습니다')
  } finally {
    assetsSubmitting.value = false
  }
}

// 批准和拒绝申请功能已废弃：新系统中充值直接进入UserStaking，无需审批流程

// 提前结算 - 将本金和收益全部结算给客户
const handleSettleAll = async (row: UserStaking) => {
  try {
    await ElMessageBox.confirm(
      `사용자 ${row.user.name}의 스테이킹을 제전 결산하시겠습니까?\n\n본금: ${formatNearAmount(row.stakedAmount)} NEAR\n수익: ${formatNearAmount(row.storedTotalRewardsNear)} NEAR\n\n본금과 수익이 모두 KRW로 전환되어 사용자 잔액에 추가되며, 스테이킹 기록이 초기화됩니다.`,
      '제전 결산 확인',
      {
        confirmButtonText: '확인',
        cancelButtonText: '취소',
        type: 'warning',
        dangerouslyUseHTMLString: false
      }
    )

    loading.value = true
    const response: any = await api.post('/api/admin/staking/settle-all', {
      userId: row.userId
    })

    const data = response.data
    ElMessage.success(
      `제전 결산 완료!\n` +
      `본금: ${data.principalNear.toFixed(4)} NEAR\n` +
      `수익: ${data.rewardNear.toFixed(4)} NEAR\n` +
      `총 금액: ${data.totalNear.toFixed(4)} NEAR\n` +
      `KRW 전환: ₩${data.totalKrw.toLocaleString()}`
    )
    await fetchStakingList()
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('제전 결산 실패:', error)
      ElMessage.error(error.message || '제전 결산에 실패했습니다')
    }
  } finally {
    loading.value = false
  }
}

// 获取状态标签类型
const getStatusTagType = (status: string) => {
  switch (status) {
    case 'PENDING': return 'warning'
    case 'APPROVED': return 'success'
    case 'ACTIVE': return 'success'
    case 'COMPLETED': return 'info'
    case 'REJECTED': return 'danger'
    default: return 'info'
  }
}

// 获取状态文本
const getStatusText = (status: string) => {
  const statusMap: Record<string, string> = {
    'PENDING': '대기중',
    'APPROVED': '승인됨',
    'ACTIVE': '활성',
    'COMPLETED': '완료',
    'REJECTED': '거부됨',
    'CANCELLED': '취소됨'
  }
  return statusMap[status] || status
}

// 提前赎回功能已废弃：新系统中用户可以直接通过正常提现流程退出

// 页码变化
const handlePageChange = (page: number) => {
  pagination.page = page
  fetchStakingList()
}

// 页面大小变化
const handleSizeChange = (size: number) => {
  pagination.limit = size
  pagination.page = 1
  fetchStakingList()
}

onMounted(() => {
  fetchStakingList()
})
</script>

<style scoped lang="scss">
.page-container {
  padding: 20px;
}

.page-header {
  margin-bottom: 24px;

  h1 {
    font-size: 24px;
    font-weight: 600;
    color: #1a202c;
    margin: 0 0 8px 0;
  }

  p {
    font-size: 14px;
    color: #64748b;
    margin: 0;
  }
}

.page-content {
  .search-card {
    margin-bottom: 20px;
  }

  .search-container {
    display: flex;
    justify-content: space-between;
    align-items: center;

    .search-left {
      .search-label {
        font-size: 16px;
        font-weight: 600;
        color: #1a202c;
      }
    }

    .search-right {
      display: flex;
      gap: 12px;

      .search-input {
        width: 400px;
      }
    }
  }

  .table-card {
    .table-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      font-weight: 500;
      color: #333;
    }

.amount {
  font-family: 'Courier New', monospace;
  font-weight: 600;
  color: #1a202c;

  &.reward {
    color: #10b981;
  }

      &.expected {
        color: #3b82f6;
      }
    }
  }

  .pagination-container {
    margin-top: 20px;
    display: flex;
    justify-content: flex-end;
  }
}

.dialog-tip {
  margin-bottom: 16px;
}

.form-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.field-hint {
  font-size: 12px;
  color: #64748b;
}

.label-chip {
  margin-right: 6px;
}

.sub-hint {
  font-size: 12px;
  color: #94a3b8;
  margin-top: 4px;
}
</style>
